/*********************************************************
          File Name:header.h
          Author: abby
          Mail: 
          Created Time: Mon 10 Aug 2015 03:31:55 PM CST
**********************************************************/

#ifndef HEADER_H_
#define HEADER_H_

#include "cfg.h"
#include "lock.h"
#include "control.h"
#include "sock.h"
#include "worker.h"
#include "signals.h"
#include "daemon.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/prctl.h>
#endif

static int worker_num = 0;
static int restart = 0;
#ifndef DBUG
static int is_daemon = 0;
#endif
static sigjmp_buf env;
static int listenfd;
static conf_t cfg;
static pid_t *workers = NULL;

static void send_signal(int timeout)
{
        int i;
        signal(SIGCHLD, SIG_IGN);

        for(i = 0; i < worker_num; i++)
        {
                if(kill(workers[i], SIGTERM) == -1)
                        perror("kill()");
        }
        sleep(timeout);              // wait timeout
        for(i = 0; i < worker_num; i++)
        {
                if(kill(workers[i], 0) != -1)
                        kill(workers[i], SIGKILL);
        }
        acc_vanish();
}

static void sig_term(int sig)
{
        send_signal(3);
        close(listenfd);
        unlink(cfg.pidfile);
        exit(0);
}

static void sig_chld(int sig)
{
        int i;
        pid_t pid;
        for(i = 0; i < worker_num; i++)
        {
                // no terminated child, return 0
                pid = waitpid(workers[i], NULL, WNOHANG);
                if(pid == workers[i])
                        create_worker(1, cfg.thread, listenfd,& workers[i]);
        }
}

static void sig_hup(int sig)
{
        signal(sig, SIG_IGN);
        restart = 1;

        send_signal(5); // wait timeout 5s

        close(listenfd);

        siglongjmp(env, 1);
}

static void sig_manager(void)
{
        install_signal_handler(SIGTERM, sig_term);
        install_signal_handler(SIGHUP, sig_hup);
        install_signal_handler(SIGCHLD, sig_chld);
}

#endif
